import { IPSAppFunc, IPSApplication } from '@ibiz/dynamic-model-api';
import { AppViewFunc } from './app-func-type/appview-func';
import { CustomFunc } from './app-func-type/custom-func';
import { JavaScriptFunc } from './app-func-type/javascript-func';
import { OpenHtmlPageFunc } from './app-func-type/openhtmlpage-func';
import { PdtAppFunc } from './app-func-type/pdtapp-func';
import { Util } from '../../util';
import { GetModelService } from '../../app';

/**
 * 应用功能服务
 *
 * @class AppFuncService
 */
export class AppFuncService {
  /**
   * 单例变量声明
   *
   * @private
   * @static
   * @memberof AppFuncService
   */
  private static AppFuncService: AppFuncService;

  /**
   * 获取 AppFuncService 单例对象
   *
   * @static
   * @return {*}
   * @memberof AppFuncService
   */
  public static getInstance(): AppFuncService {
    if (!this.AppFuncService) {
      this.AppFuncService = new AppFuncService();
    }
    return this.AppFuncService;
  }

  /**
   * 执行之前
   *
   * @param functionTag 应用功能标识
   * @param context 视图上下文
   * @param viewParam 视图参数
   * @memberof AppFuncService
   */
  private async beforeExecute(functionTag: any, context: any = {}, viewParam: any = {}) {
    const application: IPSApplication = (await GetModelService(Util.deepCopy(context))).getPSApplication();
    const appFuncs: IPSAppFunc[] | null = application?.getAllPSAppFuncs();
    let appFunc: IPSAppFunc | undefined;
    if (appFuncs) {
      appFunc = appFuncs.find((_appFunc: IPSAppFunc) => Object.is(functionTag, _appFunc.codeName));
      if (appFunc) {
        if (appFunc.getPSAppView()) {
          await appFunc.getPSAppView()?.fill(true);
          if (appFunc.getPSAppView()?.getPSAppDataEntity()) {
            await appFunc.getPSAppView()?.getPSAppDataEntity()?.fill(true);
          }
        }
        if (appFunc.getPSNavigateContexts()) {
          const localContext = Util.formatNavParam(appFunc.getPSNavigateContexts());
          Object.assign(context, localContext);
        }
        if (appFunc.getPSNavigateParams()) {
          const localViewParam = Util.formatNavParam(appFunc.getPSNavigateParams());
          Object.assign(viewParam, localViewParam);
        }
      }
    }
    return appFunc;
  }

  /**
   * 执行应用功能
   *
   * @param functionTag 应用功能标识
   * @param context 视图上下文
   * @param viewParam 视图参数
   * @param container 容器对象
   * @param isGlobalRoute 是否为全局
   * @param arg 额外参数
   * @memberof AppFuncService
   */
  public async executeAppFunction(
    functionTag: any,
    context: any = {},
    viewParam: any = {},
    container: any,
    isGlobal?: boolean,
    arg?: any,
  ) {
    const appFunc: IPSAppFunc | undefined = await this.beforeExecute(functionTag, context, viewParam);
    if (appFunc) {
      return this.executeFunc(appFunc, context, viewParam, container, isGlobal, arg);
    } else {
      App.getNoticeService().warning(`未找到 ${functionTag} 应用功能，请确认！`);
    }
  }

  /**
   * 执行功能
   *
   * @param appFunc 应用功能
   * @param context 视图上下文
   * @param viewParam 视图参数
   * @param container 容器对象
   * @param isGlobalRoute 是否为全局
   * @param arg 额外参数
   * @memberof AppFuncService
   */
  private executeFunc(
    appFunc: IPSAppFunc,
    context: any,
    viewParam: any,
    container: any,
    isGlobal?: boolean,
    arg?: any,
  ) {
    switch (appFunc.appFuncType) {
      // 打开应用视图
      case 'APPVIEW':
        return new AppViewFunc().executeFunc(appFunc, context, viewParam, container, isGlobal, arg);
      // 打开HTNL页面
      case 'OPENHTMLPAGE':
        return new OpenHtmlPageFunc().executeFunc(appFunc, context, viewParam, container, isGlobal, arg);
      // 预置应用功能
      case 'PDTAPPFUNC':
        return new PdtAppFunc().executeFunc(appFunc, context, viewParam, container, isGlobal, arg);
      // 执行JavaScript
      case 'JAVASCRIPT':
        return new JavaScriptFunc().executeFunc(appFunc, context, viewParam, container, isGlobal, arg);
      // 自定义
      case 'CUSTOM':
        return new CustomFunc().executeFunc(appFunc, context, viewParam, container, isGlobal, arg);
      default:
        App.getNoticeService().warning(`${appFunc.appFuncType} 类型应用功能暂未支持`);
    }
  }
}
